package org.tech4j.captcha.graphical.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.util.Objects;

/**
 * @program: tech4j
 * @description:
 * @author: YuKai Fan
 * @create: 2025/3/4 20:45
 **/
public class CaptchaGraphicalConfig {
    private static final Logger log = LoggerFactory.getLogger(CaptchaGraphicalConfig.class);
    public static int HAN_ZI_SIZE = 25;
    public static int HAN_ZI_SIZE_HALF = HAN_ZI_SIZE / 2;

    public final static String IMAGE_TYPE_PNG = "png";

    /**
     * 服务名称
     */
    private String serviceName;
    /**
     * ASE开关
     */
    private Boolean aseOpen;
    private FontConfig fontConfig;
    private WaterMarkConfig waterMarkConfig;
    private CaptchaConfig captchaConfig;
    private ClickWordConfig clickWordConfig;
    private RateLimiterConfig rateLimiterConfig;

    public static class ClickWordConfig {
        private String clickFont = "SourceHanSansCN-Normal.otf";

        private Integer wordTotalCount = 4;
        private Boolean fontColorRandom = Boolean.TRUE;

        private Font clickWordFont;

        public String getClickFont() {
            return clickFont;
        }

        public void setClickFont(String clickFont) {
            this.clickFont = clickFont;
        }

        public Integer getWordTotalCount() {
            return wordTotalCount;
        }

        public void setWordTotalCount(Integer wordTotalCount) {
            this.wordTotalCount = wordTotalCount;
        }

        public Boolean getFontColorRandom() {
            return fontColorRandom;
        }

        public void setFontColorRandom(Boolean fontColorRandom) {
            this.fontColorRandom = fontColorRandom;
        }

        public Font getClickWordFont() {
            return clickWordFont;
        }

        public void setClickWordFont(Font clickWordFont) {
            this.clickWordFont = clickWordFont;
        }

        public void loadClickWordFont(int fontSize, int style) {
            String clickWordFontStr = getClickFont();
            try {
                if (clickWordFontStr.toLowerCase().endsWith(".ttf") || clickWordFontStr.toLowerCase().endsWith(".ttc")
                        || clickWordFontStr.toLowerCase().endsWith(".otf")) {
                    this.clickWordFont = Font.createFont(Font.TRUETYPE_FONT,
                                    Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + clickWordFontStr)))
                            .deriveFont(Font.BOLD, fontSize);
                } else {
                    this.clickWordFont = new Font(clickWordFontStr, style, fontSize);
                }

            } catch (Exception e) {
                log.error("load font error:", e);
            }
        }
    }


    public static class CaptchaConfig {
        /**
         * 滑动干扰项(0/1/2)
         */
        private Integer interferenceOptions;

        /**
         * 自定义初始化
         */
        private Boolean initOriginal;

        /**
         * 滑动误差偏移量
         */
        private Integer slipOffset;

        public Integer getInterferenceOptions() {
            return interferenceOptions;
        }

        public void setInterferenceOptions(Integer interferenceOptions) {
            this.interferenceOptions = interferenceOptions;
        }

        public Boolean getInitOriginal() {
            return initOriginal;
        }

        public void setInitOriginal(Boolean initOriginal) {
            this.initOriginal = initOriginal;
        }

        public Integer getSlipOffset() {
            return slipOffset;
        }

        public void setSlipOffset(Integer slipOffset) {
            this.slipOffset = slipOffset;
        }
    }

    public static class FontConfig {
        /**
         * 文字字体
         */
        private String fontType;

        /**
         * 字体样式
         */
        private int fontStyle = Font.BOLD;

        /**
         * 字体大小
         */
        private int fontSize = 25;

        public String getFontType() {
            return fontType;
        }

        public void setFontType(String fontType) {
            this.fontType = fontType;
        }

        public int getFontStyle() {
            return fontStyle;
        }

        public void setFontStyle(int fontStyle) {
            this.fontStyle = fontStyle;
        }

        public int getFontSize() {
            return fontSize;
        }

        public void setFontSize(int fontSize) {
            this.fontSize = fontSize;
        }
    }

    public static class WaterMarkConfig {

        /**
         * 水印
         */
        private String waterMark;


        /**
         * 水印字体
         */
        private String waterFont;

        private Font waterMarkFont;

        public Font getWaterMarkFont() {
            return waterMarkFont;
        }

        public void setWaterMarkFont(Font waterMarkFont) {
            this.waterMarkFont = waterMarkFont;
        }

        public String getWaterMark() {
            return waterMark;
        }

        public void setWaterMark(String waterMark) {
            this.waterMark = waterMark;
        }

        public String getWaterFont() {
            return waterFont;
        }

        public void setWaterFont(String waterFont) {
            this.waterFont = waterFont;
        }

        public void loadWaterMarkFont() {
            String waterMarkFontStr = getWaterFont();
            try {
                if (waterMarkFontStr.toLowerCase().endsWith(".ttf") || waterMarkFontStr.toLowerCase().endsWith(".ttc")
                        || waterMarkFontStr.toLowerCase().endsWith(".otf")) {
                    this.waterMarkFont = Font.createFont(Font.TRUETYPE_FONT,
                                    Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + waterMarkFontStr)))
                            .deriveFont(Font.BOLD, HAN_ZI_SIZE_HALF);
                } else {
                    this.waterMarkFont = new Font(waterMarkFontStr, Font.BOLD, HAN_ZI_SIZE_HALF);
                }

            } catch (Exception e) {
                log.error("load font error:", e);
            }
        }
    }

    public static class RateLimiterConfig {

        /**
         * 请求限流开关
         */
        private Boolean requestRateLimiterEnabled;


        /**
         * get 接口 一分钟请求次数限制
         */
        private Integer requestGetRateLimiterMinuteCount;

        /**
         * 验证失败后，get接口锁定次数
         */
        private Integer requestGetRateLimiterLockCount;

        /**
         * 验证失败后，get接口锁定时间
         */
        private Integer requestGetRateLimiterLockTime;

        /**
         * check 接口 一分钟请求次数限制
         */
        private Integer requestCheckRateLimiterMinuteCount;


        /**
         * verification 接口 一分钟请求次数限制
         */
        private Integer requestVerifyRateLimiterMinuteCount;

        public Integer getRequestGetRateLimiterMinuteCount() {
            return requestGetRateLimiterMinuteCount;
        }

        public void setRequestGetRateLimiterMinuteCount(Integer requestGetRateLimiterMinuteCount) {
            this.requestGetRateLimiterMinuteCount = requestGetRateLimiterMinuteCount;
        }

        public Integer getRequestGetRateLimiterLockCount() {
            return requestGetRateLimiterLockCount;
        }

        public void setRequestGetRateLimiterLockCount(Integer requestGetRateLimiterLockCount) {
            this.requestGetRateLimiterLockCount = requestGetRateLimiterLockCount;
        }

        public Integer getRequestGetRateLimiterLockTime() {
            return requestGetRateLimiterLockTime;
        }

        public void setRequestGetRateLimiterLockTime(Integer requestGetRateLimiterLockTime) {
            this.requestGetRateLimiterLockTime = requestGetRateLimiterLockTime;
        }

        public Integer getRequestCheckRateLimiterMinuteCount() {
            return requestCheckRateLimiterMinuteCount;
        }

        public void setRequestCheckRateLimiterMinuteCount(Integer requestCheckRateLimiterMinuteCount) {
            this.requestCheckRateLimiterMinuteCount = requestCheckRateLimiterMinuteCount;
        }

        public Integer getRequestVerifyRateLimiterMinuteCount() {
            return requestVerifyRateLimiterMinuteCount;
        }

        public void setRequestVerifyRateLimiterMinuteCount(Integer requestVerifyRateLimiterMinuteCount) {
            this.requestVerifyRateLimiterMinuteCount = requestVerifyRateLimiterMinuteCount;
        }

        public Boolean getRequestRateLimiterEnabled() {
            return requestRateLimiterEnabled;
        }

        public void setRequestRateLimiterEnabled(Boolean requestRateLimiterEnabled) {
            this.requestRateLimiterEnabled = requestRateLimiterEnabled;
        }
    }

    public Boolean getAseOpen() {
        return aseOpen;
    }

    public void setAseOpen(Boolean aseOpen) {
        this.aseOpen = aseOpen;
    }

    public FontConfig getFontConfig() {
        return fontConfig;
    }

    public void setFontConfig(FontConfig fontConfig) {
        this.fontConfig = fontConfig;
    }

    public WaterMarkConfig getWaterMarkConfig() {
        return waterMarkConfig;
    }

    public void setWaterMarkConfig(WaterMarkConfig waterMarkConfig) {
        this.waterMarkConfig = waterMarkConfig;
    }

    public CaptchaConfig getCaptchaConfig() {
        return captchaConfig;
    }

    public void setCaptchaConfig(CaptchaConfig captchaConfig) {
        this.captchaConfig = captchaConfig;
    }


    public RateLimiterConfig getRateLimiterConfig() {
        return rateLimiterConfig;
    }

    public void setRateLimiterConfig(RateLimiterConfig rateLimiterConfig) {
        this.rateLimiterConfig = rateLimiterConfig;
    }

    public ClickWordConfig getClickWordConfig() {
        return clickWordConfig;
    }

    public void setClickWordConfig(ClickWordConfig clickWordConfig) {
        this.clickWordConfig = clickWordConfig;
    }

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }
}
